/// Author: Shper
/// Created: 2023/7/7

import "dart:core";

import "package:lib_core/lib_core.dart";

typedef GTMultiEngineSyncerCallback = void Function(Map<String, dynamic> arguments);

class GTMultiEngineSyncer {

  static const _KEY_ACTION = "action";

  static final Map<String, List<GTMultiEngineSyncerCallback?>>  _listenerMap = {};

  /// 通知多引擎进行数据同步
  static Future<bool> notifyToSync(Enum action, [Map<String, dynamic>? dataMap]) async {
    Map<String, dynamic> arguments = {};
    arguments[_KEY_ACTION] = _generateActionKey(action);
    if (dataMap != null) {
      arguments.addAll(dataMap);
    }
    return GTLibCoreMethodChannel.instance.notifyMultiEngineSync(arguments);
  }

  /// 监听其他引擎通知
  static addListen(Enum action, GTMultiEngineSyncerCallback callback) {
   var actionKey = _generateActionKey(action);

   var callbackList = _listenerMap[actionKey] ??= [];
   callbackList.add(callback);
   _listenerMap[actionKey] = callbackList;

   GTLogger.debug("GTMultiEngineSyncer - addListen actionKey: $actionKey, callbackSize: ${callbackList.length}");
  }

  /// 删除监听器
  static removeListen(Enum action, GTMultiEngineSyncerCallback callback) {
    var actionKey = _generateActionKey(action);

    var callbackList = _listenerMap[actionKey];
    callbackList?.removeWhere((element) => element == callback);
    // 清理空数据
    callbackList?.removeWhere((element) => element == null);

    GTLogger.debug("GTMultiEngineSyncer - removeListen actionKey: $actionKey, callbackSize: ${callbackList?.length ?? 0}");
  }

  // 分发消息
  static dispatchListens(Map<String, dynamic> arguments) {
    var action = arguments[_KEY_ACTION] as String?;
    if (action == null || action.isEmpty) {
      GTLogger.error("GTMultiEngineSyncer - The action is invalid.");
      return;
    }

    // 分发消息
    var callbackList = _listenerMap[action] ??= [];
    GTLogger.debug("GTMultiEngineSyncer - callback size: ${callbackList.length}");
    for (var element in callbackList) {
      try {
        element?.call(arguments);
      } catch (e) {
        GTLogger.error(e);
      }
    }
  }

  /// 根据枚举生成 action key
  static String _generateActionKey(Enum action) {
    return "${action.runtimeType}.${action.name}";
  }

}